const { ipcRenderer, shell } = require('electron');
const { DownloadStatus } = require('../common/DownloadStatus');
const { stringify } = require('../common/json');

let openDevTools = false;
ipcRenderer.on('devtools-enabled', () => {
    openDevTools = true;
});

const downloadBtnTextMap = {
    [DownloadStatus.Init]: '停止',
    [DownloadStatus.Preparing]: '停止', 
    [DownloadStatus.Parsing]: '停止', 
    [DownloadStatus.Downloading]: '停止',
    [DownloadStatus.DownloadFail]: '重新下载',
    [DownloadStatus.Merging]: '停止',
    [DownloadStatus.MergeFail]: '重新下载',
    [DownloadStatus.Success]: '重新下载',
    [DownloadStatus.Stopping]: '停止中...',
    [DownloadStatus.Stopped]: '重新下载',
    [DownloadStatus.Error]: '重新下载',
};

window.app = new Vue({
    el: '#app',
    data: function () {
        return {
            // 常量
            DownloadStatus,
            downloadBtnTextMap,
            // 下载信息
            version: '',
            m3u8_url: '',
            m3u8_urls: '',
            ts_dir: '',
            ts_urls: [],
            m3u8_url_prefix: '',
            dlg_header_visible: false,
            dlg_newtask_visible: false,
            // 设置
            config_save_dir: '',
            config_title_filter: '',
            config_custom_url_suffix: '',
            config_suggestDomainList: '',
            config_ffmpeg: '',
            config_proxy: '',
            config_player: '',
            config_requestUA: '',
            config_downloadTsWithHeader: null,
            // ===
            headers: '',
            myKeyIV: '',
            myLocalKeyIV: '',
            taskName: '',
            taskIsDelTs: true,
            allVideos: [],
            catTabPane: '',
            tabPane: '',
            tsMergeType: 'speed',
            tsMergeProgress: 0,
            tsMergeStatus: '',
            tsMergeMp4Path: '',
            tsMergeMp4Dir: '',
            tsTaskName: '',
            downloadSpeed: '0 MB/s',
            playlists: [],
            playlistUri: '',
            taskAdding: false,
            addTaskMessage: '',
            navigatorInput: '',
            navigatorUrl: 'https://haokan.baidu.com/?sfrom=baidu-top',
            browserVideoUrls: [],
            platform: '',
            requestHeaders: {},
            urlSearch: '',
            // webview
            canGoBack: false,
            canGoForward: false,
            // 下载项操作
            selectedItem: null,
        }
    },
    methods: {
        installEvent: function (e) {
            let that = this;

            ipcRenderer.on('message', this.message.bind(this));

            ipcRenderer.on('open-select-m3u8-reply', function (event, data) {
                that.m3u8_url = data;
            });
            ipcRenderer.on('open-select-ts-dir-reply', function (event, data) {
                that.ts_dir = data;
            });
            ipcRenderer.on('open-select-ts-select-reply', function (event, data) {
                that.ts_urls = data;
                that.ts_dir = `选择了 [${that.ts_urls.length}] 个视频`;
            });

            ipcRenderer.on('task-add-reply', function (event, data) {
                if (data.code != 1) {
                    that.dlg_newtask_visible = false;
                    that.taskName = '';
                    that.m3u8_url = '';
                    that.m3u8UrlChange();
                    that.notifyTaskStatus(data.code, data.message);
                    return;
                }
                that.playlists = data.playlists;
                that.playlistUri = that.playlists[0].uri;
                that.addTaskMessage = "请选择一种画质";
            });
            ipcRenderer.on('task-notify-create', function (event, data) {
                console.debug('状态变化-创建', data.__seq__, data.id, data.statusCode, data.status);
                that.allVideos.splice(0, 0, data);
            });
            ipcRenderer.on('task-notify-update', (event, data) => {
                console.debug('状态变化-更新', data.__seq__, data.id, data.statusCode, data.status);
                const video = this.allVideos.find(v => v.id === data.id);
                Object.assign(video, data);
            });
            ipcRenderer.on('task-notify-end', (event, data) => {
                console.debug('状态变化-结束', data.__seq__, data.id, data.statusCode, data.status);
                const video = this.allVideos.find(v => v.id === data.id);
                Object.assign(video, data);
            });
            ipcRenderer.on('start-merge-ts-status', function (event, msg) {
                if (msg.progress != -1) that.tsMergeProgress = msg.progress;
                if (msg.status) that.tsMergeStatus = msg.status;
                if (msg.code == 1) {
                    that.tsMergeMp4Dir = msg.dir;
                    that.tsMergeMp4Path = msg.path;
                }
            });

            ipcRenderer.on('delvideo-reply', (event, { success, error, video }) => {
                if (!success) {
                    this.$message.error(error || '删除失败，原因未知。');
                    return;
                }
                const index = this.allVideos.findIndex(v => v.id === video.id);
                if (index !== -1) {
                    this.allVideos.splice(index, 1);
                    this.$message.success('删除成功。');
                } else {
                    this.$message.error('删除异常，未找到删除的视频。');
                }
            });

            let browser = document.querySelector('#browser');
            let navigateEvent = (e) => {
                that.navigatorInput = e.url;
                that.browserVideoUrls = [];
                this.refreshNavigateStatus();
            }
            browser.addEventListener('load-commit', () => {
                const webContentsId = browser.getWebContentsId();
                console.debug('webContents id:', webContentsId);
                ipcRenderer.send('webview-loaded', webContentsId);
            });
            browser.addEventListener('will-navigate', navigateEvent);
            browser.addEventListener('did-navigate', navigateEvent);
            browser.addEventListener('dom-ready', () => {
                if (openDevTools) {
                    browser.openDevTools();
                }
            });
            browser.addEventListener('context-menu', () => {
                const webContentsId = browser.getWebContentsId();
                console.debug('webContents id:', webContentsId);
                ipcRenderer.send('open-context-menu', webContentsId);
            });
            ipcRenderer.on('context-menu-click', (_, type) => {
                if (type === 'devtools') {
                    if (browser.isDevToolsOpened()) {
                        browser.closeDevTools();
                    } else {
                        browser.openDevTools();
                    }
                }
            });
        },
        message: function (_, data) {
            const {
                version, downloadSpeed,
                config_ffmpeg, config_save_dir, config_title_filter, config_proxy, config_player, config_custom_url_suffix,
                config_suggestDomainList, config_requestUA, config_downloadTsWithHeader,
                videoDatas, browserVideoItem, platform, requestHeaders,
            } = data;
            version && (this.version = version);
            downloadSpeed && (this.downloadSpeed = downloadSpeed);
            config_ffmpeg && (this.config_ffmpeg = config_ffmpeg);
            config_save_dir && (this.config_save_dir = config_save_dir);
            config_title_filter && (this.config_title_filter = config_title_filter);
            config_custom_url_suffix && (this.config_custom_url_suffix = config_custom_url_suffix);
            config_suggestDomainList && (this.config_suggestDomainList = config_suggestDomainList.join(','));
            config_requestUA && (this.config_requestUA = config_requestUA);
            config_proxy && (this.config_proxy = config_proxy);
            config_player && (this.config_player = config_player);
            config_downloadTsWithHeader != null && (this.config_downloadTsWithHeader = config_downloadTsWithHeader);
            videoDatas && (this.allVideos = videoDatas);
            console.debug('视频列表', this.allVideos);
            platform && (this.platform = platform);
            if (browserVideoItem) {
                const { url, headers } = browserVideoItem;
                const savedHeaders = this.requestHeaders[url];
                if (!headers && savedHeaders) {
                    browserVideoItem.headers = savedHeaders;
                }
                const { browserVideoUrls } = this;
                const existIndex = browserVideoUrls.findIndex(d => d.url === url)
                if (existIndex === -1) {
                    browserVideoUrls.push(browserVideoItem);
                } else {
                    browserVideoUrls.splice(existIndex, 1, browserVideoItem);
                }
            }
            if (requestHeaders) {
                this.requestHeaders = Object.assign(this.requestHeaders, requestHeaders);
            }
        },
        sniffNewTask: function (item) {
            if (!this.clickNewTask()) {
                return;
            }
            this.catTabPane = '0';
            this.tabPane = '0';
            this.m3u8_url = item.url;
            const headers = JSON.parse(item.headers || '{}');
            this.headers = Object.keys(headers)
                .map(key => `${key}: ${headers[key]}`)
                .join('\n');
        },
        clickNaviagte: _.debounce(function (url) {
            if (!url) return;
            console.debug('load...', this.navigatorInput, url);
            if (!/^https?\:\/\//.test(url)) {
                url = 'http://' + url;
            }
            this.navigatorInput = url;
            if (this.navigatorUrl !== url) {
                browser.stop();
                this.navigatorUrl = url;
                // browser.loadURL(url, {
                //     extraHeaders: [
                //         'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                //         'Accept-Encoding: gzip, deflate, br, zstd',
                //         'Accept-Language: zh-CN,zh;q=0.9',
                //         'Priority: u=0, i',
                //         'Sec-Ch-Ua: "Not(A:Brand";v="99", "Google Chrome";v="133", "Chromium";v="133"',
                //         'Sec-Ch-Ua-Mobile: ?0',
                //         'Sec-Ch-Ua-Platform: "Windows"',
                //         'Sec-Fetch-Dest: document',
                //         'Sec-Fetch-Mode: navigate',
                //         'Sec-Fetch-Site: none',
                //         'Sec-Fetch-User: ?1',
                //     ].join('\n'),
                // });
            } else {
                browser.reload();
            }
            this.requestHeaders = {};
        }, 300),
        clickAClick: function (e) {
            e.preventDefault();
            console.log(e.target.href);
            shell.openExternal(e.target.href);
        },
        clickStartHookUrl: function (e) {
            ipcRenderer.send('new-hook-url-window');
        },
        clickClose: function (e) {
            // ipcRenderer.send('hide-windows');
            ipcRenderer.send('exit');
        },
        clickNewTask: function (e) {
            if (!this.config_save_dir) {
                this.tabPane = "setting";
                this.$message({ title: '提示', type: 'error', message: "请先设置存储路径，再开始下载视频", offset: 100, duration: 1000 });
                return false;
            }
            this.dlg_newtask_visible = true;
            const { config_title_filter } = this;
            let pageTitle = this.getWebviewPageTitle();
            pageTitle = pageTitle.replace(new RegExp(config_title_filter, 'g'), '');
            this.taskName = pageTitle;
            this.m3u8_url = '';
            this.m3u8UrlChange();
            return true;
        },
        clickNewTaskOK: function (e) {
            if (this.m3u8_url != '') {
                let m3u8_url = this.m3u8_url;
                if (this.playlistUri != '') {
                    const uri = this.playlistUri;
                    if (!uri.startsWith('http')) {
                        m3u8_url = uri[0] == '/' ? (m3u8_url.substr(0, m3u8_url.indexOf('/', 10)) + uri) :
                            (m3u8_url.replace(/\/[^\/]*((\?.*)|$)/, '/') + uri);
                    }
                    else {
                        m3u8_url = uri;
                    }
                }

                this.taskAdding = true;
                ipcRenderer.send('task-add', {
                    url: m3u8_url,
                    headers: this.headers,
                    myKeyIV: this.myKeyIV,
                    taskName: this.taskName,
                    taskIsDelTs: this.taskIsDelTs,
                    url_prefix: this.m3u8_url_prefix
                });

                this.addTaskMessage = "正在检查链接..."
            }
            else {
                this.$message({ title: '提示', type: 'error', message: "请输入正确的M3U8-URL或者导入(.m3u8)文件", offset: 100, duration: 1000 });
            }
        },
        clickClearTask: function (e) {
            ipcRenderer.send('task-clear');
            this.allVideos = [];
        },
        clickNewTaskMuti: function (e) {
            if (!this.config_save_dir) {
                this.tabPane = "setting";
                this.$message({ title: '提示', type: 'error', message: "请先设置存储路径，再开始下载视频", offset: 100, duration: 1000 });
                return;
            }
            if (this.m3u8_urls != '') {
                ipcRenderer.send('task-add-muti', {
                    m3u8_urls: this.m3u8_urls,
                    headers: this.headers,
                    taskIsDelTs: this.taskIsDelTs,
                    myKeyIV: '',
                    taskName: ''
                });
                this.dlg_newtask_visible = false;
                this.taskName = '';
            }
            else {
                this.$message({ title: '提示', type: 'error', message: "请输入正确的M3U8-URL", offset: 100, duration: 1000 });
            }
        },
        clickOpenConfigDir: function (e) {
            ipcRenderer.send("open-config-dir");
        },
        async clickItemOptData(video, opt) {
            let optParam;
            console.debug('Operate video...', opt, video);
            switch (opt) {
                case 'opendir':
                    optParam = video.status === '已完成' ? video.videopath : video.dir;
                    break;
                case 'StartOrStop':
                    if (video.statusCode === DownloadStatus.Success) {
                        try {
                            await this.$confirm('资源已完成下载，确认要重新下载吗？', '提示', {
                                confirmButtonText: '确认',
                                cancelButtonText: '取消',
                                type: 'warning',
                            });
                        } catch(e) {
                            return;
                        }
                    }
                    optParam = video.id;
                    break;
                case 'delvideo':
                    if (video.status !== '已完成') {
                        try {
                            await this.$confirm('资源未完成下载，是否确认删除？', '提示', {
                                confirmButtonText: '确认',
                                cancelButtonText: '取消',
                                type: 'warning',
                            });
                        } catch(e) {
                            return;
                        }
                    }
                    optParam = video.id;
                    break;
                case 'playvideo':
                    optParam = { src: video.videopath || video.url, headers: video.headers };
                    // optParam = video.url;
                    break;
            }
            ipcRenderer.send(opt, optParam);
        },
        getPlaylistLabel: function (playlist) {
            if (!playlist || !playlist.attributes) return '';
            const attr = playlist.attributes;
            if (attr.BANDWIDTH) {
                return `码率 - ${attr.BANDWIDTH}`;
            }
            if (attr.bandwidth) {
                return `码率 - ${attr.bandwidth}`;
            }
            if (attr.RESOLUTION) {
                return `分辨率 - ${attr.RESOLUTION.width}x${attr.RESOLUTION.height}`;
            }
            if (attr.resolution) {
                return `分辨率 - ${attr.resolution.width}x${attr.resolution.height}`;
            }
            return '链接 - ' + playlist.uri;
        },
        onTitleFilterChange(titleFilter) {
            titleFilter = titleFilter.trim();
            this.config_title_filter = titleFilter;
            ipcRenderer.send('set-config', { key: 'TitleFilter', value: titleFilter });
        },
        onCustomUrlSuffixChange(customUrlSuffix) {
            customUrlSuffix = customUrlSuffix.trim();
            this.config_custom_url_suffix = customUrlSuffix;
            ipcRenderer.send('set-config', { key: 'CustomUrlSuffix', value: customUrlSuffix });
        },
        onPlayerChange(player) {
            ipcRenderer.send('set-config', { key: 'config_player', value: player });
        },
        proxyChange: function () {
            ipcRenderer.send('set-config', { key: 'config_proxy', value: this.config_proxy });
        },
        m3u8UrlChange: function () {
            this.playlists = [];
            this.playlistUri = '';
            this.addTaskMessage = "请输入M3U8视频源";
        },
        notifyTaskStatus: function (code, message) {
            this.taskAdding = false;
            this.$notify({ title: '提示', type: (code == 0 ? 'success' : 'error'), message: message, showClose: true, duration: 3000, position: 'bottom-right' });
        },
        clickOpenLogDir: function (e) {
            ipcRenderer.send('open-log-dir');
        },
        clickSelectM3U8: function (e) {
            ipcRenderer.send('open-select-m3u8');
        },
        clickSelectTSDir: function (e) {
            ipcRenderer.send('open-select-ts-dir');
        },
        clickStartMergeTS: function (e) {
            this.tsMergeMp4Dir = '';
            this.tsMergeMp4Path = '';
            this.tsMergeProgress = 0;
            this.tsMergeStatus = '';
            if (!this.config_save_dir) {
                this.tabPane = "setting";
                this.$message({ title: '提示', type: 'error', message: "请先设置存储路径，再开始下载视频", offset: 100, duration: 1000 });
                return;
            }
            ipcRenderer.send('start-merge-ts', {
                ts_files: this.ts_urls,
                mergeType: this.tsMergeType,
                name: this.tsTaskName
            });
        },
        clickClearMergeTS: function (e) {
            this.ts_dir = '';
            this.ts_urls = [];
            this.tsTaskName = '';
            this.tsMergeMp4Dir = '';
            this.tsMergeMp4Path = '';
            this.tsMergeProgress = 0;
            this.tsMergeStatus = '';
        },
        clickOpenMergeTSDir: function (e) {
            ipcRenderer.send('opendir', this.tsMergeMp4Dir, this.tsMergeMp4Path);
        },
        clickPlayMergeMp4: function (e) {
            ipcRenderer.send('playvideo', { src: this.tsMergeMp4Path });
        },
        dropM3U8File: function (e) {
            e.preventDefault();

            if (!e.dataTransfer ||
                !e.dataTransfer.files ||
                e.dataTransfer.files.length == 0) {
                return;
            }
            let p = e.dataTransfer.files[0].path;
            this.m3u8_url = `file:///${p}`;
        },
        dropTSFiles: function (e) {
            e.preventDefault();

            if (!e.dataTransfer ||
                !e.dataTransfer.files ||
                e.dataTransfer.files.length == 0) {
                return;
            }
            let _filePath = [];
            for (let index = 0; index < e.dataTransfer.files.length; index++) {
                const f = e.dataTransfer.files[index];
                if (f.path.endsWith('.ts') || f.path.endsWith('.TS')) {
                    _filePath.push(f.path);
                }
            }
            if (_filePath.length) {
                this.ts_urls = _filePath;
                this.ts_dir = `选择了 [${_filePath.length}] 个视频`;

            } else if (e.dataTransfer.files.length == 1) {
                this.ts_dir = e.dataTransfer.files[0].path;
                ipcRenderer.send('open-select-ts-dir', e.dataTransfer.files[0].path);
            }
        },
        clickRefreshComment: function (e) {
            var GUEST_INFO = ['nick', 'mail', 'link'];
            var guest_info = 'nick'.split(',').filter(function (item) {
                return GUEST_INFO.indexOf(item) > -1
            });
            console.log(guest_info)
            var notify = 'false' == true;
            var verify = 'false' == true;
            new Valine({
                el: '.vcomment',
                notify: notify,
                verify: verify,
                appId: "dYhmAWg45dtYACWfTUVR2msp-gzGzoHsz",
                appKey: "SbuBYWY21MPOSVUCTHdVlXnx",
                placeholder: "可以在这里进行咨询交流",
                pageSize: '100',
                avatar: 'mm',
                lang: 'zh-cn',
                meta: guest_info,
                recordIP: true,
                path: '/m3u8-downloader'
            });
        },
        // 获取webview标题
        getWebviewPageTitle() {
            const pageTitle = browser.getTitle().trim();
            return pageTitle;
        },
        // webview导航
        refreshVebview() {
            browser.reload();
            refreshNavigateStatus();
        },
        goBack() {
            browser.goBack();
        },
        goForward() {
            browser.goForward();
        },
        refreshNavigateStatus() {
            this.canGoBack = browser.canGoBack();
            this.canGoForward = browser.canGoForward();
        },
        navigateInputFocus() {
            this.urlSearch = '';
        },
        navigateInputBlur() {
            this.navigatorInput = this.navigatorUrl;
            setTimeout(() => {
                this.$refs.navigateInput.close();
            }, 200);
        },
        navigateUrlInput(value) {
            this.urlSearch = value.trim();
        },
        // 建议域名列表
        onSuggestDomainListChange(suggestDomainListStr) {
            const suggestDomainList = suggestDomainListStr.trim().split(',').map(s => s.trim());
            this.config_suggestDomainList = suggestDomainList.join(',');
            ipcRenderer.send('set-config', { key: 'suggestDomainList', value: suggestDomainList });
        },
        // UA
        onRequestUAChange(ua) {
            this.config_requestUA = ua;
            ipcRenderer.send('set-config', { key: 'requestUA', value: ua });  
        },
        // ts 下载选项
        onDownloadTsWithHeaderChange(downloadTsWithHeader) {
            this.config_downloadTsWithHeader = downloadTsWithHeader;
            ipcRenderer.send('set-config', { key: 'downloadTsWithHeader', value: downloadTsWithHeader });
        },
        urlSuggestions(str, cb) {
            const { urlSearch } = this;
            const list = this.config_suggestDomainList.split(',');
            const resultList = !urlSearch ? list : list.filter(s => s.indexOf(urlSearch) !== -1);
            cb(resultList.map(s => ({ value: s })));
        },
        // === 下载项操作 ===
        onItemClick(item) {
            this.selectedItem = item.id;
        },
        // 播放视频
        playVideo(url, headers) {
            ipcRenderer.send('playvideo', { src: url, headers });
        },
    },
    mounted: function () {
        this.installEvent();
    },
});
